package cn.sxgan.core.services.impl;


import cn.sxgan.common.consts.CommonConst;
import cn.sxgan.common.consts.RedisConst;
import cn.sxgan.common.entity.SysUser;
import cn.sxgan.common.entity.query.SysUserQuery;
import cn.sxgan.common.entity.sys.GlobalUser;
import cn.sxgan.common.entity.sys.RequestHolder;
import cn.sxgan.common.enums.ResStatusEnum;
import cn.sxgan.common.exception.ApiException;
import cn.sxgan.common.exception.AuthorityException;
import cn.sxgan.common.redis.RedisUtil;
import cn.sxgan.common.response.Result;
import cn.sxgan.common.utils.CommonUtils;
import cn.sxgan.common.utils.JwtUtils;
import cn.sxgan.common.utils.PasswordEncoderUtils;
import cn.sxgan.core.services.IAuthService;
import cn.sxgan.db.mappers.SysUserMapper;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 认证服务实现
 * @Author: sxgan
 * @Date: 24/7/12 17:50
 * @Version: 1.0
 **/
@Slf4j
@Service
public class AuthServiceImpl implements IAuthService {
    
    @Resource
    RedisUtil redisUtil;
    
    @Resource
    SysUserMapper userMapper;
    
    @Override
    public Result<Map<String, String>> userAuthByEmail(GlobalUser globalUser) {
        String checkStr = checkImgVerifyCode(globalUser);
        if (checkStr != null) {
            return Result.fail(Maps.newHashMap(), checkStr);
        }
        HashMap<String, String> map = Maps.newHashMap();
        SysUserQuery userQuery = new SysUserQuery();
        userQuery.setEmail(globalUser.getEmail());
        List<SysUser> userList = userMapper.selectUserByCondition(userQuery);
        if (userList.size() > 0) {
            SysUser user = userList.get(0);
            if (user.getDelFlag() == 1) {
                throw new ApiException(ResStatusEnum.EXCEPTION_STATUS_913.getMsg());
            }
            // 判断密码是否正确,加密密码与库中（user对象）的password比对是否相同
            if (PasswordEncoderUtils.matches(user.getPassword(), globalUser.getPassword())) {
                // 允许登陆，生成令牌
                // 写入用户信息
                HashMap<String, Object> tokenMap = new HashMap<>();
                tokenMap.put("email", user.getEmail());
                tokenMap.put("id", user.getUserId());
                String token = JwtUtils.createToken(tokenMap);
                globalUser.setId(user.getUserId());
                globalUser.setUserName(user.getUserName());
                globalUser.setToken(token);
                globalUser.setUserType(user.getUserType());
                redisUtil.set(RedisConst.LOGIN_TOKEN_PREFIX + token, globalUser, CommonConst.LOGIN_TIME_1,
                        TimeUnit.DAYS);
                map.put("token", token);
                return Result.success(map, 0);
            } else {
                return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_703.getMsg());
            }
        } else {
            return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_701.getMsg());
        }
    }
    
    
    private String checkImgVerifyCode(GlobalUser globalUser) {
        if (globalUser != null && StringUtils.isBlank(globalUser.getImgVerifyCode())) {
            return ResStatusEnum.EXCEPTION_STATUS_900.getMsg();
        }
        String imgCode = redisUtil.get(RedisConst.IMG_CAPTCHA_PREFIX + globalUser.getVerToken(), String.class);
        redisUtil.del(RedisConst.IMG_CAPTCHA_PREFIX + globalUser.getVerToken());
        if (imgCode == null) {
            return ResStatusEnum.EXCEPTION_STATUS_708.getMsg();
        } else if (!imgCode.equalsIgnoreCase(globalUser.getImgVerifyCode())) {
            return ResStatusEnum.EXCEPTION_STATUS_705.getMsg();
        }
        return null;
    }
    
    /**
     * 检查参数
     *
     * @param globalUser 用户参数
     * @return 检查结果
     */
    public Result<Map<String, String>> checkParam(GlobalUser globalUser) {
        String email = globalUser.getEmail();
        String password = globalUser.getPassword();
        String verifyCode = globalUser.getVerifyCode();
        if (StringUtils.isBlank(email) || StringUtils.isBlank(password) || StringUtils.isBlank(verifyCode)) {
            return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_704.getCode(),
                    ResStatusEnum.EXCEPTION_STATUS_704.getMsg());
        }
        
        // 查询当前邮箱的验证码并验证
        String captchaCacheVal = redisUtil.get(RedisConst.CARD_CAPTCHA_PREFIX + email, String.class);
        log.info("AuthServiceImpl.signupUserByEmail captchaCacheVal = {}", captchaCacheVal);
        
        String[] captchaCacheValArr = null;
        if (captchaCacheVal != null) {
            captchaCacheValArr = captchaCacheVal.split("_");
            if (!captchaCacheValArr[0].equals(verifyCode)) {
                return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_705.getCode(),
                        ResStatusEnum.EXCEPTION_STATUS_705.getMsg());
            }
        } else {
            return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_705.getCode(),
                    ResStatusEnum.EXCEPTION_STATUS_705.getMsg());
        }
        
        long sendTime = Long.parseLong(captchaCacheValArr[2]);
        long currentTime = System.currentTimeMillis();
        if (currentTime - sendTime > 60 * 5 * 1000) {
            // return "验证码已过期";
        }
        return Result.success();
    }
    
    @Override
    public Result<Map<String, String>> signupUserByEmail(GlobalUser globalUser) {
        Result<Map<String, String>> result = checkParam(globalUser);
        if (!result.getStatus().equals(ResStatusEnum.DELETE_STATUS_200.getCode())) {
            return result;
        }
        String email = globalUser.getEmail();
        // 查询邮箱是否已经注册
        SysUserQuery userQuery = new SysUserQuery();
        userQuery.setEmail(email);
        List<SysUser> userList = userMapper.selectUserByCondition(userQuery);
        if (userList.size() > 0) {
            return Result.fail(Maps.newHashMap(), ResStatusEnum.EXCEPTION_STATUS_706.getCode(),
                    ResStatusEnum.EXCEPTION_STATUS_706.getMsg());
        }
        // 注册账号
        SysUser user = new SysUser();
        user.setUserName(CommonUtils.generateRandomCode(12).toUpperCase(Locale.ROOT));
        user.setEmail(email);
        // 加密
        
        // 生成盐
        String salt = CommonUtils.generateRandomCode(20);
        String slatPass = PasswordEncoderUtils.encode(globalUser.getPassword(), salt);
        user.setSalt(salt);
        user.setPassword(slatPass);
        int insert = userMapper.insert(user);
        if (insert == 0) {
            throw new AuthorityException(
                    ResStatusEnum.EXCEPTION_STATUS_702.getCode(), ResStatusEnum.EXCEPTION_STATUS_702.getMsg());
        }
        return Result.success(Maps.newHashMap(), 0);
    }
    
    @Override
    public Result<String> updatePwd(GlobalUser globalUser) {
        Result<Map<String, String>> result = checkParam(globalUser);
        if (!result.getStatus().equals(ResStatusEnum.DELETE_STATUS_200.getCode())) {
            return Result.fail(result.getMessage());
        }
        GlobalUser currentUser = RequestHolder.getCurrentUser();
        return null;
    }
}